using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Kinect2;

using TIMESPAN = System.Int64;

public class ColorBasic : MonoBehaviour {

	KinectSensor kinectSensor;
	ColorFrameReader colorFrameReader;
	Texture2D texture;
	GameObject status;

	void Start ()
    {
		kinectSensor = KinectSensor.GetDefault();
        colorFrameReader = kinectSensor.ColorFrameSource.OpenReader();
        colorFrameReader.FrameArrived += Reader_ColorFrameArrived;

        FrameDescription colorFrameDescription = kinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
        texture = new Texture2D(colorFrameDescription.Width, colorFrameDescription.Height, TextureFormat.BGRA32, false);
            
        kinectSensor.IsAvailableChanged += Sensor_IsAvailableChanged;
		kinectSensor.Open ();

        InitializeComponent();		
	}
	
	void Update () 
    {
        EventRouter.Check();
	}

	void OnApplicationQuit()
	{
        if (colorFrameReader != null)
            colorFrameReader.Dispose();
        colorFrameReader = null;

		if (kinectSensor != null)
			kinectSensor.Close ();
        kinectSensor = null;
	}

    void InitializeComponent()
    {
		GameObject color = GameObject.Find("color");
		color.guiTexture.texture = texture;
		status = GameObject.Find ("status");
        status.guiText.text = kinectSensor.IsAvailable ? "Running" : "No ready Kinect found!";
    }

    void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
    {
        using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
        {
            if (colorFrame != null)
            {
                FrameDescription colorFrameDescription = colorFrame.FrameDescription;
                using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer())
                {
                    if ((colorFrameDescription.Width == texture.width)
                        && (colorFrameDescription.Height == texture.height))
                    {
                        int width = colorFrameDescription.Width;
                        int height = colorFrameDescription.Height;
                        byte[] buffer = new byte[width * height * 4];
                        colorFrame.CopyConvertedFrameDataToArray(buffer, ColorImageFormat.Rgba);
                        ProcessColor(buffer);
                    }
                }
            }
        }
    }

    void Sensor_IsAvailableChanged(object sender, IsAvailableChangedEventArgs e)
    {
        status.guiText.text = kinectSensor.IsAvailable ? "Running" : "Kinect not available!";
    }

	void ProcessColor(byte[] data)
	{
		int width = texture.width;
		int height = texture.height;
		byte[] data2 = new byte[width * height * 4];
		for (int j = 0; j < height; j++){
			int dst = width * 4 * (height - 1 - j);
			int src = width * 4 * j;
			Array.Copy(data, src, data2, dst, width * 4);
		}
		texture.LoadRawTextureData (data2);
		texture.Apply();
	}
}
